//
// Created by Administrator on 2021/11/29.
//

#include "StringUtil.h"

/**
 * 截取字符串，原字符串不变
 * @param start 起始索引
 * @param len 长度
 * @return 截取后字符串
 */
std::string StringUtil::subStr(std::string s, unsigned int start,unsigned int len) {

    m_check((start >= 0 && len >= 0), format("the start[%d] and length[%d] should greater than or eq 0", start, len).c_str());
    m_check((start < s.length() && (start + len) <= s.length()), format("the start[%d]/length[%d] is out of length[%d]", start, len, s.length()).c_str());

    std::string cp;
    unsigned int end = start + len;
    end = end > s.length() ? s.length() : end;
    for(unsigned int i = start; i < end; i++){
        cp += s[i];
    }
    return cp;
}


/**
 * 字符串分割
 * @param splitStr 分隔符
 * @param outArray 分割后数组
 */
void StringUtil::split(std::string s, std::string splitStr, std::vector<std::string> &outArray) {
    if(splitStr.empty() || s.empty()){
        outArray.push_back(s);
        return;
    }

    int posStart, posEnd;
    //记录分隔符的长度
    int len = splitStr.length();
    posStart = 0;
    posEnd= s.find(splitStr.c_str());
    while(posEnd != std::string::npos )
    {
        outArray.push_back(s.substr(posStart, posEnd - posStart) );
        posStart = posEnd + len;
        // 从str的pos1位置开始搜寻spacer
        posEnd = s.find(splitStr.c_str(), posStart);
    }
    if(posStart != s.length()) //分割最后一个部分
        outArray.push_back(s.substr(posStart));
}

/**
 * 字符串分割
 * @param splitStr 分隔符
 */
std::vector<std::string> StringUtil::split(std::string s, std::string splitStr) {
    std::vector<std::string> outArray;
    split(s, splitStr, outArray);
    return outArray;
}


/**
* 字符串分割,支持正则表达式
* @param regex 分隔符,支持正则表达式
* @param outArray 分割后数组
*/
void StringUtil::splitWithRegex(std::string s, std::string regex, std::vector<std::string> &outArray) {
    std::regex ex(regex.c_str());

    unsigned int startPos = 0;
    for (std::sregex_iterator it(s.begin(), s.end(), ex), end;
         it != end;
         ++it)
    {
        unsigned int pos = it->position();
        unsigned int len = it->length();
        if(startPos != pos){
            outArray.emplace_back(s.substr(startPos, it->position()));
        }
        startPos = pos + len;
    }
    if(startPos != s.length()) //分割最后一个部分
        outArray.emplace_back(s.substr(startPos));
}

/**
* 字符串分割,支持正则表达式
* @param regex 分隔符,支持正则表达式
*/
std::vector<std::string> StringUtil::splitWithRegex(std::string s, std::string regex) {
    std::vector<std::string> outArray;
    splitWithRegex(s, regex, outArray);
    return outArray;
}

/**
 * 字符在字符串中最开始出现的索引值
 * @param c 字符
 * @return 索引，如果不存在返回 -1
 */
int StringUtil::indexOf(std::string s, char c) {
    int len = s.length();
    for (int i = 0; i < len; i++) {
        if(c == s[i]){
            return i;
        }
    }

    return -1;
}

/**
 * 字符在字符串中最后出现的索引值
 * @param c 字符
 * @return 索引，如果不存在返回 -1
 */
int StringUtil::lastIndexOf(std::string s, char c) {
    int len = s.length();
    for (int i = len - 1; i >= 0; i--) {
        if(c == s[i]){
            return i;
        }
    }
    return -1;
}

/**
* 获得类名
*/
std::string StringUtil::getClassName(const std::string& filePath) {
    int s = lastIndexOf(filePath, '\\');
    int e = lastIndexOf(filePath, '.');
    if(e > s && s + 1 <= e){
        return filePath.substr(s + 1, e);
    }
    return "";
}

/**
 * 获取文件名+后缀
 * @param filePath 文件路径
 * @return 文件名+后缀
 */
std::string StringUtil::getFileName(const std::string& filePath) {
    int s = lastIndexOf(filePath, '\\');
    unsigned long len = filePath.length();
    if(len > s && s + 1 <= len){
        return filePath.substr(s + 1, len);
    }
    return "";
}


/**
 * int 转 字符串
 * @param i 数字
 * @return 字符串
 */
std::string StringUtil::toString(int i) {
    char c[64];
    sprintf(c, "%d", i);
    return c;
}

/**
 * float 转 字符串
 * @param f 数字
 * @return 字符串
 */
std::string StringUtil::toString(float f) {
    char c[64];
    if(f >= 0){
        sprintf(c, "%.4f", f);
    }else{
        sprintf(c, "%.3f", f);
    }
    return c;
}

/**
 * 格式化字符串
 * @param fmt 模板
 * @param ... 变量
 * @return 格式化字符串
 */
std::string StringUtil::format(const char *fmt, ...) {
    char msg[STR_LENGTH];
    va_list arg;
    va_start(arg, fmt);
    _vsnprintf(msg, STR_LENGTH, fmt, arg);
    va_end(arg);

    return msg;
}


/**
 * 去除首尾空格
 * @return
 */
std::string StringUtil::trim(std::string s) {
    if (s.empty()) {
        return s;
    }
    s.erase(0, s.find_first_not_of(SPACE));
    s.erase(s.find_last_not_of(SPACE) + 1);

    return s;
}

/**
 * 判断是否以head开头
 * @param head
 * @return
 */
bool StringUtil::startWith(std::string s, std::string head) {
    return s.compare(0, head.size(), head) == 0;
}













